Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Nov 5, 2025

Contributors page now supports dynamic filtering by project (?project=glossary) and role (?role=project-manager) while keeping all data in static HTML for search engine indexing.

Changes

Data generation (tenzing.py)

  • Extract and normalize project/role names to lowercase-hyphenated format ("Replications & Reversals""replications-and-reversals")
  • Generate HTML list items with data-projects and data-roles attributes containing comma-separated normalized values
  • Apply HTML attribute escaping to prevent injection

Template (tenzing_template.md)

  • Add filter control UI (hidden until URL params present)
  • Wrap contributor list in <ul id="contributor-list"> for JavaScript access

Client-side filtering (contributor-filter.js)

  • Parse URL parameters and filter DOM nodes matching data attributes
  • Display filtered results with count and active filter info
  • Provide clear filters button to return to full list

Implementation

<!-- Generated output structure -->
<ul id="contributor-list">
  <li data-projects="glossary,impact-on-students" 
      data-roles="writing---original-draft,investigation">
    <strong><a href="https://orcid.org/...">Jane Doe</a></strong>
    contributed to <a href="...">Glossary</a> with <em>Writing</em>...
  </li>
</ul>

All contributor data remains in static HTML before JavaScript executes, ensuring search engines index everything. Filtering is purely additive client-side enhancement.

Usage Examples

/contributors                                           # Full list
/contributors?project=glossary                         # Glossary contributors only
/contributors?role=project-manager                     # All project managers
/contributors?project=glossary&role=writing---original-draft  # Combined filter

Screenshots

Filtered by Project (Glossary)
image

Combined Filter (Project + Role)
image

Security

  • XSS prevention via input sanitization (escapeHtml())
  • HTML attribute escaping in Python (html.escape())
  • Safe DOM manipulation (no innerHTML injection)
  • CodeQL: 0 vulnerabilities

Documentation

  • CONTRIBUTORS_FILTERING.md - User guide with normalization rules and examples
  • scripts/forrt_contribs/README.md - Script usage for regenerating page
  • IMPLEMENTATION_NOTES.md - Architecture and maintenance notes

Deployment

To activate filtering on existing contributors data:

cd scripts/forrt_contribs
python3 tenzing.py
cp tenzing.md ../../content/contributors/tenzing.md
Original prompt

This section details on the original issue you should resolve

<issue_title>Add project- and role-based filtering to Contributors page</issue_title>
<issue_description>Summary

The current Contributors page (tenzing.md) presents a comprehensive, static list of all FORRT contributors. We want to enhance it by allowing users to filter dynamically by project (e.g., /contributors?project=glossary) and optionally by role (e.g., /contributors?role=project-lead) — without losing search-engine visibility of individual names.

This feature will require adjustments to both the data generation script and the website layout.

Goals / Deliverables

Data generation enhancements

Extend the existing tenzing.py script so that the generated Markdown includes lightweight HTML attributes or data tags per contributor entry:

  • Balazs Aczel contributed to ...
  • Ensure each project and role are normalized (lowercase, hyphen-safe) for consistent filtering.

    Keep the generated file fully static (for SEO), but semantically structured for client-side filtering.

    Website display logic

    On page load, check for project and/or role parameters in the URL.

    If parameters are present:

    Hide the full contributor list.

    Dynamically render a focused list of contributors matching the filter, e.g.:

    Project: Glossary

    Balazs Aczel — Project co-lead
    Maria Lopez — Writing

    If no parameters are provided, display the full unfiltered overview (contributors → projects → roles), preserving the current hierarchy.

    Optional UI features

    Add basic dropdowns or buttons for project and role selection that update the URL (?project= / ?role=) without reloading.

    Maintain accessibility and crawlability — all data must exist in the static HTML before filtering.

    Technical constraints

    No reduction in search engine indexability (all names and projects remain visible in the static HTML).

    The dynamic filtering is purely client-side (no new API or server-side filtering).

    Should work seamlessly with existing Hugo build output and templating.

    Deliverables checklist

    Updated tenzing.py script outputting data-projects and data-roles attributes.

    Modified template (tenzing_template.md) with placeholders ready for those attributes.

    JS file for URL parameter parsing and DOM filtering logic.

    Verified filtered view layout (project-centric, role-centric).

    Maintained full SEO visibility.

    Success criteria

    Visiting /contributors?project=glossary displays only contributors involved in “Glossary” with clean name–role pairs.

    Visiting /contributors?role=project-lead lists all contributors serving as project leads, across projects.

    Viewing /contributors without parameters shows the full static list.

    Search engines can still index all contributor names and text.</issue_description>

    Comments on the Issue (you are @copilot in this section)


    💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

    Copilot AI and others added 6 commits November 5, 2025 10:17
    Co-authored-by: LukasWallrich <60155545+LukasWallrich@users.noreply.github.com>
    Co-authored-by: LukasWallrich <60155545+LukasWallrich@users.noreply.github.com>
    Co-authored-by: LukasWallrich <60155545+LukasWallrich@users.noreply.github.com>
    Co-authored-by: LukasWallrich <60155545+LukasWallrich@users.noreply.github.com>
    Co-authored-by: LukasWallrich <60155545+LukasWallrich@users.noreply.github.com>
    Co-authored-by: LukasWallrich <60155545+LukasWallrich@users.noreply.github.com>
    Copilot AI changed the title [WIP] Add project- and role-based filtering to Contributors page Add URL parameter filtering to Contributors page with full SEO preservation Nov 5, 2025
    Copilot AI requested a review from LukasWallrich November 5, 2025 10:32
    @github-actions
    Copy link
    Contributor

    github-actions bot commented Nov 5, 2025

    👍 All image files/references (if any) are in webp format, in line with our policy.

    @LukasWallrich LukasWallrich marked this pull request as ready for review November 5, 2025 16:56
    @LukasWallrich LukasWallrich requested a review from a team as a code owner November 5, 2025 16:56
    @LukasWallrich
    Copy link
    Contributor

    ⚠️ This PR was attempted to be deployed to staging as part of an aggregated deployment, but had merge conflicts and was skipped. Please resolve conflicts and try again. View staging at: https://staging.forrt.org

    @LukasWallrich
    Copy link
    Contributor

    ⚠️ This PR was attempted to be deployed to staging as part of an aggregated deployment, but had merge conflicts and was skipped. Please resolve conflicts and try again. View staging at: https://staging.forrt.org

    @LukasWallrich
    Copy link
    Contributor

    ✅ This PR has been deployed to staging as part of an aggregated deployment. View at: https://staging.forrt.org

    10 similar comments
    @LukasWallrich
    Copy link
    Contributor

    ✅ This PR has been deployed to staging as part of an aggregated deployment. View at: https://staging.forrt.org

    @LukasWallrich
    Copy link
    Contributor

    ✅ This PR has been deployed to staging as part of an aggregated deployment. View at: https://staging.forrt.org

    @LukasWallrich
    Copy link
    Contributor

    ✅ This PR has been deployed to staging as part of an aggregated deployment. View at: https://staging.forrt.org

    @LukasWallrich
    Copy link
    Contributor

    ✅ This PR has been deployed to staging as part of an aggregated deployment. View at: https://staging.forrt.org

    @LukasWallrich
    Copy link
    Contributor

    ✅ This PR has been deployed to staging as part of an aggregated deployment. View at: https://staging.forrt.org

    @LukasWallrich
    Copy link
    Contributor

    ✅ This PR has been deployed to staging as part of an aggregated deployment. View at: https://staging.forrt.org

    @LukasWallrich
    Copy link
    Contributor

    ✅ This PR has been deployed to staging as part of an aggregated deployment. View at: https://staging.forrt.org

    @LukasWallrich
    Copy link
    Contributor

    ✅ This PR has been deployed to staging as part of an aggregated deployment. View at: https://staging.forrt.org

    @LukasWallrich
    Copy link
    Contributor

    ✅ This PR has been deployed to staging as part of an aggregated deployment. View at: https://staging.forrt.org

    @LukasWallrich
    Copy link
    Contributor

    ✅ This PR has been deployed to staging as part of an aggregated deployment. View at: https://staging.forrt.org

    @LukasWallrich
    Copy link
    Contributor

    ✅ This PR has been deployed to staging as part of an aggregated deployment. View at: https://staging.forrt.org

    2 similar comments
    @LukasWallrich
    Copy link
    Contributor

    ✅ This PR has been deployed to staging as part of an aggregated deployment. View at: https://staging.forrt.org

    @LukasWallrich
    Copy link
    Contributor

    ✅ This PR has been deployed to staging as part of an aggregated deployment. View at: https://staging.forrt.org

    @LukasWallrich LukasWallrich marked this pull request as draft November 12, 2025 16:39
    @LukasWallrich
    Copy link
    Contributor

    This needs local testing - I'm afraid that running data processing on this branch will lead to an artefact that break master deployment?

    @LukasWallrich
    Copy link
    Contributor

    ✅ This PR has been deployed to staging as part of an aggregated deployment. View at: https://staging.forrt.org

    @github-actions github-actions bot added the content related Relevant to website content label Jan 3, 2026
    @rivaquiroga rivaquiroga marked this pull request as ready for review January 3, 2026 17:16
    @rivaquiroga rivaquiroga self-assigned this Jan 3, 2026
    @rivaquiroga
    Copy link
    Contributor

    Copilot's initial proposal didn't work as-is. While the JS code for filtering was functional, the Python code in tenzing.py generated a mix of Markdown and HTML that Hugo couldn't parse correctly. Commit f2e9dc fixes this parsing issue.

    Commit bb2721b implements additional features:

    • In Copilot’s original implementation, filtering by a project (e.g., Glossary) would return all contributors to that project along with all of their other FORRT contributions. The filter now returns only the contributions specific to the selected project. To make this possible, contributions are no longer presented as a numbered list.
    • Added dropdown menus for filtering. Users can now select projects and roles from dropdown menus instead of manually editing the URL (although URL-based filtering still works). Menu options are dynamically generated from the tenzing sheets data, so if new roles are added, the options update when re-rendering the site.
    • Implemented anchor links for contributors with ORCID iD (e.g. https://forrt.org/contributors/#0000-0001-9000-8513). This is intentionally limited to people with ORCID iD to encourage adoption (also, names aren't reliable unique identifiers).
    • Moved @flavioazevedo to the end of the contributor list (as requested by him).

    This is now ready for review @forrtproject/team-website

    @LukasWallrich
    Copy link
    Contributor

    LukasWallrich commented Jan 3, 2026

    Staging Deployment Status

    This PR has been successfully deployed to staging as part of an aggregated deployment.

    Deployed at: 2026-01-05 17:02:27 UTC
    Staging URL: https://staging.forrt.org

    The staging site shows the combined state of all compatible open PRs.

    @github-actions
    Copy link
    Contributor

    github-actions bot commented Jan 5, 2026

    ✅ Spell Check Passed

    No spelling issues found in this PR! 🎉

    @rivaquiroga
    Copy link
    Contributor

    I'm not sure why the staging site doesn't show the changes, but this is how it looks locally:

    Captura de pantalla 2026-01-04 a la(s) 10 17 41 p m

    @github-actions
    Copy link
    Contributor

    github-actions bot commented Jan 5, 2026

    ✅ Spell Check Passed

    No spelling issues found in this PR! 🎉

    @richarddushime
    Copy link
    Contributor

    I'm not sure why the staging site doesn't show the changes, but this is how it looks locally:

    Captura de pantalla 2026-01-04 a la(s) 10 17 41 p m

    Data processing is still picking up the master branch artifacts not the one run on this branch
    its safe to merge now

    Copy link
    Contributor

    @richarddushime richarddushime left a comment

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    LGTM 👍

    @richarddushime richarddushime merged commit 18b415b into master Jan 5, 2026
    8 of 9 checks passed
    @richarddushime richarddushime deleted the copilot/add-filtering-to-contributors-page branch January 5, 2026 17:15
    @richarddushime
    Copy link
    Contributor

    The changes will be visible after data processing run

    @richarddushime
    Copy link
    Contributor

    Now available here https://forrt.org/contributors/

    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

    Labels

    content related Relevant to website content

    Projects

    None yet

    Development

    Successfully merging this pull request may close these issues.

    Add project- and role-based filtering to Contributors page

    4 participants